/*
 * Listener.java
 */
package RoomNanny.SpotListener;

import com.sun.spot.peripheral.radio.RadioFactory;
import com.sun.spot.peripheral.radio.IRadioPolicyManager;
import com.sun.spot.io.j2me.radiostream.*;
import com.sun.spot.io.j2me.radiogram.*;
import com.sun.spot.util.IEEEAddress;
import java.text.DateFormat;
import java.util.Date;
import java.io.*;
import java.util.*;
import javax.microedition.io.*;

import RoomNanny.*;

/**
 * This is a host application for RoomNanny's Java SunSPOTs. This Listener class
 * simply listens over a radio channel for incoming data from a SunSPOT, then
 * pushes that data to a remote database.
 *
 * To build this in ant without a physical basestation, run this command:
 * ant host-run -Dbasestation.shared=true -Dbasestation.not.required=true
 */
public class Listener {

    // Broadcast port on which we listen for sensor samples
    private static final int HOST_PORT = 67;
    
    /**
     * Main program execution
     */
    private void run() throws Exception {

        RadiogramConnection inConnection;   // incoming radiogram connection
        Datagram dg;                        // datagram for incoming data
        DateFormat fmt = DateFormat.getTimeInstance();
        DB database = new DB();             // database to send data to

        Hashtable addresses = new Hashtable();  // addresses and IDs of SPOTs

        try {
            // Open up a server-side broadcast radiogram connection
            // to listen for sensor readings being sent by different SPOTs
            inConnection = (RadiogramConnection) Connector.open("radiogram://:"
                    + HOST_PORT);
            dg = inConnection.newDatagram(inConnection.getMaximumLength());
        } catch (Exception e) {
            System.err.println("setUp caught " + e.getMessage());
            throw e;
        }
        try {
            database.connect("cs340.pugetsound.edu/RoomNanny", false);
        } catch (DBException e) {
            System.err.println("No connection...");
        }

        // Main data collection loop
        while (true) {
            String addr = null;
            long time = 0;
            int spotIDReading = -1;
            double tempReading = 0;
            boolean lightReading = false;
            double accelXReading = 0;
            double accelYReading = 0;
            double accelZReading = 0;

            try {
                // Read sensor sample received over the radio
                inConnection.receive(dg);
                addr = dg.getAddress(); // read sender's address

                if (dg.readShort() == 1) {
                    // This must be a request for an ID!
                    int newID = database.registerSensor(addr);

                    // new outgoing datagram
                    RadiogramConnection outConnection =
                            (RadiogramConnection) Connector.open("radiogram://broadcast:" + HOST_PORT);
                    Datagram outDG = outConnection.newDatagram(inConnection.getMaximumLength());

//                    if (addresses.containsKey(addr)) {
//                        newID = (Integer) addresses.get(addr);
//                        System.out.println("Assigning previously seen SPOT " +
//                                           addr + " to ID number " + newID);
//                    } else {
//                        // randomly generate ID numbers for now...
//                        //Random rand = new Random(System.currentTimeMillis());
//                        //newID = rand.nextInt(7) + 1;
//
//
//
//                        System.out.println("Assigning SPOT " + addr +
//                                           " to ID number " + newID);
//                    }

                    System.out.println("Assigning spot " + addr + " to ID "
                                       + newID);

                    outDG.writeUTF(addr);
                    outDG.writeInt(newID);
                    outConnection.send(outDG);
                    outConnection.close();
                } else {
                    // Get the sensor's readings
                    spotIDReading = dg.readInt();
                    time = dg.readLong(); // read time of the reading
                    tempReading = dg.readDouble(); // read the sensor value
                    lightReading = dg.readBoolean();
                    accelXReading = dg.readDouble();
                    accelYReading = dg.readDouble();
                    accelZReading = dg.readDouble();
                    System.out.println(fmt.format(new Date(time)) + " from: "
                            + addr + " (" + spotIDReading + ") temp = " + tempReading
                            + " light = " + lightReading
                            + " X = " + accelXReading
                            + " Y = " + accelYReading
                            + " Z = " + accelZReading);
                                    // Get data to the database
                    System.out.println("Sending data...");
                    try {
                        database.pushData(spotIDReading,
                                          (float) tempReading,
                                          RoomNanny.DoorState.Still,
                                          lightReading);
                    } catch (DBException e) {
                        System.err.println("pushData failed... " + e);
                    }
                }
            } catch (Exception e) {
                System.err.println("Caught " + e +
                                   " while reading sensor samples.");
                throw e;
            }
        }

        // the nature of the loop is such that we will never disconnect...
//        try {
//            testDB.disconnect();
//        } catch (Exception e) {
//            System.err.println("Disconnect failed...");
//        }
    }

    /**
     * Start up the host application.
     *
     * @param args any command line arguments
     */
    public static void main(String[] args) throws Exception {
        Listener app = new Listener();
        app.run();
    }
}
